package org.shangrila.bme.mb;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.model.SelectItem;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.event.RowEditEvent;
import org.shangrila.app.sys.cfg.AppInitInfo;
import org.shangrila.app.sys.shiro.SecUtil;
import org.shangrila.bme.eo.AppFileInfo;
import org.shangrila.bme.eo.BmeContProd;
import org.shangrila.bme.eo.BmeContract;
import org.shangrila.bme.eo.BmeMaterial;
import org.shangrila.bme.eo.BmeSaleout;
import org.shangrila.bme.eo.BmeSaleoutDetail;
import org.shangrila.comm.dao.DbAccess;
import org.shangrila.comm.helper.IDHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Named
@SessionScoped
public class SaleoutMB implements Serializable {
	private static final long serialVersionUID = -513146464217112L;
	private final Logger log = LoggerFactory.getLogger(this.getClass());

    private BmeSaleout io = new BmeSaleout();//录入    
	private List<BmeSaleout> vo = new ArrayList<BmeSaleout>(); //查询

	private List<BmeSaleoutDetail> vod = new ArrayList<BmeSaleoutDetail>(); //详情
	private BmeSaleoutDetail selectedd = new BmeSaleoutDetail();//录入以及选择详情信息	

	private List<BmeContract> bmeContracts; 	
	private BmeContract selectedContract = new BmeContract(); 

	private List<BmeContProd> bmeContProds; 	
	private BmeContProd selectedContProd = new BmeContProd(); 
	private List<BmeContProd> selectedContProds;
	
	private BmeMaterial selectedMaterial = new BmeMaterial(); 

	//获取相关数据字典
	private List<SelectItem> itemsStatus = AppInitInfo.getDropdownList("SaleoutStatus"); 

	private String operator;	
	private String uploadedFile="";
	private String uploadedFileImage="";

	//附件上传页面参数传递
	private String uploadForType="4";
	private String uploadForId="0";
	private String uploadForName="0";

	@Inject
	private DbAccess db;
	@Inject
	BmeCommEntityService bmeCommEntityService; 
	@Inject
	private AttachUploadMB attachUploadMB;
	
	@PostConstruct
    public void init() {
		try{
			operator = SecUtil.getCachedShiroUser().getUserno();
		}
		catch(Exception ex){
			operator="bme";
		}
		newIo();
		initdata();
	}

	public void initdata() {
    	bmeContracts = bmeCommEntityService.getBmeContracts();
    	//selectedContract = bmeContracts.get(0);
    	//bmeContProds = selectedContract.getBmeContProds();
	}
	
    public void newIo() {
    	initdata();
    	io = new BmeSaleout();
    	io.setId(IDHelper.genStrID(20));
    	io.setAmount(new BigDecimal(0));
    	io.setStatus("1");
    	vo = new ArrayList<BmeSaleout>();
    	vod = new ArrayList<BmeSaleoutDetail>();
    	attachUploadMB.setVoList(new ArrayList<AppFileInfo>());
    	attachUploadMB.setUploadedFileImage("");
    }    

	//null
	public String nullAction() {
		return null;
	}
	
	//提交:相应的合同产品中的销售数量增加以及出库单金额
	public String commitAction() {
		if(!validDetailAction()) {
			return null;
		}
		//相应的合同产品中的销售数量增加
		db.beginTransaction();
		for(BmeContProd bcp:io.getBmeContract().getBmeContProds()) {
			if(null==bcp.getSaleQuantity()) bcp.setSaleQuantity(new BigDecimal(0));
			for(BmeSaleoutDetail bsd:vod) {
				if(bcp.getBmeMaterial().getId().equals(bsd.getBmeMaterial().getId()))
					bcp.setSaleQuantity(bsd.getMquantity());
			    	//四舍五入进位处理    	
					bcp.setSaleRate(bcp.getSaleQuantity().divide(bcp.getQuantity().setScale(4,BigDecimal.ROUND_UP).multiply(new BigDecimal(100))));
					db.update(bcp);
			}			
		}
		
		//出库单金额
		BigDecimal sumMoney = new BigDecimal(0);
		db.beginTransaction();
		for(BmeSaleoutDetail bsd:vod) {
			sumMoney = sumMoney.add(null==bsd.getAmount() ? new BigDecimal(0) : bsd.getAmount());//订单金额
		}
		io.setAmount(sumMoney);
		db.update(io);
		
		db.commitTransaction();
		

		AppInitInfo.showMessage("出库单数据生成", "处理成功");
		return null;
	}
    
	//新增
    public void onAdd() {   
    	newIo();
    	AppInitInfo.showMessage("新增出库单", "处理成功");    	
    }
    //保存
	public String saveAction() {		
		db.beginTransaction();
		io.setBmeContract(selectedContract);
		io.setContName(selectedContract.getName());
		io.setBmeCustomer(selectedContract.getBmeCustomer());
		io.setAddress(selectedContract.getShippingAddress());
		io.setCreateTime(new Date());
		io.setOperator(operator);
		db.insert(io);
		db.commitTransaction();
		
		AppInitInfo.showMessage("出库单录入", "处理成功");
		uploadForId=io.getId();
		uploadForName=io.getContName();
		return null;
	}
	//选择合同
	public void onSelectedContract() {
		 bmeContProds = selectedContract.getBmeContProds();
		 io.setAddress(selectedContract.getShippingAddress());
		 io.setBmeCustomer(selectedContract.getBmeCustomer());
	}

	//验证详单操作的有效性
	public boolean validDetailAction(){
		if(null==io.getCreateTime()) {
			AppInitInfo.showMessage("warn","操作无效", "请确保单据主体信息已经保存");
			return false;
		}
		else
			return true;
	}
    //保存
	public String saveDetail() {
		if(!validDetailAction()) {
			return null;
		}
		List<BmeSaleoutDetail> bpdList = new ArrayList<BmeSaleoutDetail>();
		for(BmeContProd bcp:selectedContProds) {
			selectedd = new BmeSaleoutDetail();
			selectedd.setId(IDHelper.genStrID(20));
	     	selectedd.setBmeMaterial(bcp.getBmeMaterial());
	     	selectedd.setMdesc(bcp.getBmeMaterial().getMdesc());
	     	selectedd.setMunit(bcp.getBmeMaterial().getMunit());
	     	selectedd.setMquantity(bcp.getQuantity());
	     	selectedd.setMprice(bcp.getPrice());
	     	selectedd.setAmount(bcp.getAmount());
	     	
	     	selectedd.setSpeci(bcp.getSpeci());
	     	selectedd.setProcessQuantity(bcp.getProcessQuantity());
	     	selectedd.setProcessSpeci(bcp.getProcessSpeci());
	     	selectedd.setProcessTeck(bcp.getProcessTeck());
	     	
			selectedd.setBmeSaleout(io);
			selectedd.setCreateTime(new Date());
			selectedd.setOperator(operator);
			bpdList.add(selectedd);
		}     
		try {
			io.setAmount(calculateAmount());
			db.beginTransaction();	
			for(BmeSaleoutDetail bcp:bpdList) {
				db.insert(bcp);
			}			
			db.update(io);
			db.commitTransaction();
			
			vod.addAll(bpdList);
			io.setBmeSaleoutDetails(vod);
			AppInitInfo.showMessage("新增详情录入", "处理成功");
			selectedContProds=null;
		}catch(Exception e) {			
			AppInitInfo.showMessage("error","新增详情失败", "请确保单据主体信息已经保存");
			log.error(e.getLocalizedMessage());
			try {
				db.rollbackTransaction();
			}catch(Exception ex) {	}
		} 		
		return null;
	}
	//删除
    public String delDetail() {
    	vod.remove(selectedd);
    	io.setAmount(calculateAmount());
		db.beginTransaction();
		db.update(io);
		db.delete(selectedd);
		db.commitTransaction();
		
        AppInitInfo.showMessage("删除记录", "处理成功");
        return null;
    }
	
	//编辑
    public void onRowEdit(RowEditEvent event) {
    	selectedd = vod.get(vod.indexOf((BmeSaleoutDetail) event.getObject()));
     	selectedd.setAmount( (null==selectedd.getMprice() ? new BigDecimal(0) : selectedd.getMprice()).multiply((null==selectedd.getMquantity() ? new BigDecimal(0) : selectedd.getMquantity())) );
    	io.setAmount(calculateAmount());
    	db.beginTransaction();
    	db.update(io);
    	db.update(selectedd);
    	db.commitTransaction();
    	AppInitInfo.showMessage("详单修改", "处理成功");
    }
    
    public void onRowCancel(RowEditEvent event) {
    	AppInitInfo.showMessage("取消修改", "处理成功");
    }
    
    //计算出库单的金额字段
    public BigDecimal calculateAmount() {
    	BigDecimal bd = new BigDecimal(0);
    	for(BmeSaleoutDetail bse:vod) {    		
    		bd = bd.add( null==bse.getAmount() ? new BigDecimal(0) : bse.getAmount());    		
    	}
    	return bd;
    }
    
	public BmeSaleout getIo() {
		return io;
	}

	public void setIo(BmeSaleout io) {
		this.io = io;
	}

	public List<BmeSaleoutDetail> getVod() {
		return vod;
	}

	public void setVod(List<BmeSaleoutDetail> vod) {
		this.vod = vod;
	}

	public BmeSaleoutDetail getSelectedd() {
		return selectedd;
	}

	public void setSelectedd(BmeSaleoutDetail selectedd) {
		this.selectedd = selectedd;
	}

	public BmeMaterial getSelectedMaterial() {
		return selectedMaterial;
	}

	public void setSelectedMaterial(BmeMaterial selectedMaterial) {
		this.selectedMaterial = selectedMaterial;
	}

	public String getUploadedFile() {
		return uploadedFile;
	}

	public void setUploadedFile(String uploadedFile) {
		this.uploadedFile = uploadedFile;
	}

	public String getUploadedFileImage() {
		return uploadedFileImage;
	}

	public void setUploadedFileImage(String uploadedFileImage) {
		this.uploadedFileImage = uploadedFileImage;
	}

	public BmeContract getSelectedContract() {
		return selectedContract;
	}

	public void setSelectedContract(BmeContract selectedContract) {
		this.selectedContract = selectedContract;
	}

	public List<BmeContract> getBmeContracts() {
		return bmeContracts;
	}

	public void setBmeContracts(List<BmeContract> bmeContracts) {
		this.bmeContracts = bmeContracts;
	}

	public String getUploadForType() {
		return uploadForType;
	}

	public void setUploadForType(String uploadForType) {
		this.uploadForType = uploadForType;
	}

	public String getUploadForId() {
		return uploadForId;
	}

	public void setUploadForId(String uploadForId) {
		this.uploadForId = uploadForId;
	}

	public String getUploadForName() {
		return uploadForName;
	}

	public void setUploadForName(String uploadForName) {
		this.uploadForName = uploadForName;
	}

	public List<BmeSaleout> getVo() {
		return vo;
	}

	public void setVo(List<BmeSaleout> vo) {
		this.vo = vo;
	}

	public List<BmeContProd> getBmeContProds() {
		return bmeContProds;
	}

	public void setBmeContProds(List<BmeContProd> bmeContProds) {
		this.bmeContProds = bmeContProds;
	}

	public BmeContProd getSelectedContProd() {
		return selectedContProd;
	}

	public void setSelectedContProd(BmeContProd selectedContProd) {
		this.selectedContProd = selectedContProd;
	}

	public List<BmeContProd> getSelectedContProds() {
		return selectedContProds;
	}

	public void setSelectedContProds(List<BmeContProd> selectedContProds) {
		this.selectedContProds = selectedContProds;
	}

	public List<SelectItem> getItemsStatus() {
		return itemsStatus;
	}

	public void setItemsStatus(List<SelectItem> itemsStatus) {
		this.itemsStatus = itemsStatus;
	}
	
}